<?php
namespace Core\Libs\Inflexao;

class Inflexao {

	public static $_arrayRegrasInflexao = array('plural' => array('/^(.*)ao$/i' => '\1oes',
														   '/^(.*)(r|s|z)$/i' => '\1\2es',
														   '/^(.*)(a|e|o|u)l$/i' => '\1\2is',
														   '/^(.*)il$/i' => '\1is',
														   '/^(.*)(m|n)$/i' => '\1ns',
														   '/(.*)x$/' => '\1',
														   '/^(.*)$/i' => '\1s'
													),

										 'singular' => array('/^(.*)(oes|aes|aos)$/i' => '\1ao',
															 '/^(.*)(a|e|o|u)is$/i' => '\1\2l',
															 '/^(.*)e?is$/i' => '\1il',
															 '/^(.*)(r|s|z)es$/i' => '\1\2',
															 '/^(.*)ns$/i' => '\1m',
															 '/(.*)x$/' => '\1',
															 '/^(.*)s$/i' => '\1'
													),

										 'transliteracao' => array(
															'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
															'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
															'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
															'/Ò|Ó|Ô|Õ|Ö|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
															'/Ù|Ú|Û|Ü|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
															'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
															'/Ð|Ď|Đ/' => 'D',
															'/Ĝ|Ğ|Ġ|Ģ/' => 'G',
															'/Ĥ|Ħ/' => 'H',
															'/Ĵ/' => 'J',
															'/Ķ/' => 'K',
															'/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
															'/Ñ|Ń|Ņ|Ň/' => 'N',
															'/Ŕ|Ŗ|Ř/' => 'R',
															'/Ś|Ŝ|Ş|Š/' => 'S',
															'/Ţ|Ť|Ŧ/' => 'T',
															'/Ý|Ÿ|Ŷ/' => 'Y',
															'/Ź|Ż|Ž/' => 'Z',
															'/Ŵ/' => 'W',
															'/Æ|Ǽ/' => 'AE',
															'/ß/'=> 'ss',
															'/Ĳ/' => 'IJ',
															'/Œ/' => 'OE',
															'/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
															'/è|é|ê|ë|ē|ĕ|ė|ę|ě|&/' => 'e',
															'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
															'/ò|ó|ô|õ|ö|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
															'/ù|ú|û|ü|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
															'/ç|ć|ĉ|ċ|č/' => 'c',
															'/ð|ď|đ/' => 'd',
															'/ĝ|ğ|ġ|ģ/' => 'g',
															'/ĥ|ħ/' => 'h',
															'/ĵ/' => 'j',
															'/ķ/' => 'k',
															'/ĺ|ļ|ľ|ŀ|ł/' => 'l',
															'/ñ|ń|ņ|ň|ŉ/' => 'n',
															'/ŕ|ŗ|ř/' => 'r',
															'/ś|ŝ|ş|š|ſ/' => 's',
															'/ţ|ť|ŧ/' => 't',
															'/ý|ÿ|ŷ/' => 'y',
															'/ŵ/' => 'w',
															'/ź|ż|ž/' => 'z',
															'/æ|ǽ/' => 'ae',
															'/ĳ/' => 'ij',
															'/œ/' => 'oe',
															'/ƒ/' => 'f'
												)
										);

	public static $_arrayPluralIrregular = array('abdomen' => 'abdomens',
										  'alemao' => 'alemaes',
										  'artesa' => 'artesaos',
										  'as' => 'ases',
										  'bencao' => 'bencaos',
										  'cao' => 'caes',
										  'capelao' => 'capelaes',
										  'capitao' => 'capitaes',
										  'chao' => 'chaos',
										  'charlatao' => 'charlataes',
										  'cidadao' => 'cidadaos',
										  'consul' => 'consules',
										  'cristao' => 'cristaos',
										  'dificil' => 'dificeis',
										  'email' => 'emails',
										  'escrivao' => 'escrivaes',
										  'fossel' => 'fosseis',
										  'germens' => 'germen',
										  'grao' => 'graos',
										  'hifens' => 'hifen',
										  'irmao' => 'irmaos',
										  'liquens' => 'liquen',
										  'mal' => 'males',
										  'mao' => 'maos',
										  'orfao' => 'orfaos',
										  'pais' => 'paises',
										  'pai' => 'pais',
										  'pao' => 'paes',
										  'perfil' => 'perfis',
										  'projetil' => 'projeteis',
										  'reptil' => 'repteis',
										  'sacristao' => 'sacristaes',
										  'sotao' => 'sotaos',
										  'tabeliao' => 'tabeliaes'
										 );

	public static $_arrayNaoInflexionaveis = array('atlas',
											'lapis',
											'onibus',
											'pires',
											'virus'
										   );

	final public static function adicionarRegras($tipo, $regras) {

		if(is_array(&$$regras)) {

			if(self::$_arrayRegrasInflexao[$tipo] === NULL) {

				self::$_arrayRegrasInflexao[$tipo] = $regras;
			}

			else {

				self::$_arrayRegrasInflexao =& array_merge(&self::$_arrayRegrasInflexao[$tipo], $regras);
			}

			return TRUE;
		}

		return FALSE;
	}

	final public function adicionarSeparador($arrayAdicionarSeparador, $limite, $separador = '') {

		$i = 1;

		foreach($arrayAdicionarSeparador as $valor) {

			if($i < $limite) {

				$stringSeparadorAdicionado .= $valor.$separador;
			}

			else {

				$stringSeparadorAdicionado .= $valor;
			}

			$i++;
		}

		unset($arrayAdicionarSeparador, $limite, $separador);

		return $stringSeparadorAdicionado;
	}

	final public static function &_singularizarOuPluralizar($arrayParametros, $tipo = 'plural', $tipoCaixa = 'caixaBaixa', $posicaoCaractere = NULL, $separador = '') {

		if(!is_array(&$arrayParametros)) {

			$arrayParametros =& preg_split('/,( {1,})?/i', &$arrayParametros);
			$arrayParametros = array('palavra' => $arrayParametros, 'tipo' => $tipo, 'tipoCaixa' => $tipoCaixa, 'posicaoCaractere' => $posicaoCaractere, 'separador' => $separador);
			unset($tipo, $tipoCaixa, $posicaoCaractere, $separador);		
		}

		$arrayParametros =& \Core\Uses\SetArrayParametros($arrayParametros, array('palavra' => NULL, 'tipo' => 'plural', 'tipoCaixa' => 'caixaBaixa', 'posicaoCaractere' => NULL, 'separador' => ''));

		if(!is_array(&$arrayParametros['palavra'])) {

			$arrayParametros['palavra'] = array($arrayParametros['palavra']);		
		}

		if(!is_string(&$arrayParametros['separador'])) {

			$arrayParametros['separador'] = '';
		}

		$arrayParametros['quantidadePalavras'] =& count($arrayParametros['palavra']);

		for($arrayParametros['countPalavras'] = 0; $arrayParametros['countPalavras'] < $arrayParametros['quantidadePalavras']; $arrayParametros['countPalavras']++) {

			$arrayParametros['auxPalavra'] = strtolower($arrayParametros['palavra'][$arrayParametros['countPalavras']]);
			$arrayParametros['palavraEncontrada'] = FALSE;

			foreach(self::$_arrayNaoInflexionaveis as $arrayParametros['regra']) {

				if(preg_match('/'.$arrayParametros['regra'].'/i', &$arrayParametros['auxPalavra'])) {

					$arrayParametros['palavraEncontrada'] = TRUE;

					break;
				}
			}

			if(!$arrayParametros['palavraEncontrada']) {

				if($arrayParametros['tipo'] === 'plural') {

					if(array_key_exists(&$arrayParametros['auxPalavra'], &self::$_arrayPluralIrregular)) {

						$arrayParametros['palavraEncontrada'] = TRUE;
					}
				}

				elseif($arrayParametros['tipo'] === 'singular') {

					if($arrayParametros['indice'] =& array_search(&$arrayParametros['auxPalavra'], &self::$_arrayPluralIrregular)) {

						$arrayParametros['auxPalavra'] =& $arrayParametros['index'];
						$arrayParametros['palavraEncontrada'] = TRUE;
					}
				}

				else {

					$arrayParametros['auxPalavra'] =& $arrayParametros['palavra'][$arrayParametros['countPalavras']];
					$arrayParametros['palavraEncontrada'] = TRUE;
				}
			}

			if(!$arrayParametros['palavraEncontrada']) {

				foreach(self::$_arrayRegrasInflexao[$arrayParametros['tipo']] as $arrayParametros['regra'] => $arrayParametros['substituir']) {

					$arrayParametros['regraAplicadaPalavra'] =& preg_replace($arrayParametros['regra'], $arrayParametros['substituir'], $arrayParametros['auxPalavra']);

					if($arrayParametros['auxPalavra'] !== $arrayParametros['regraAplicadaPalavra']) {

						$arrayParametros['auxPalavra'] = $arrayParametros['regraAplicadaPalavra'];
						$arrayParametros['palavraEncontrada'] = TRUE;

						break;
					}
				}
			}

			if($arrayParametros['palavraEncontrada']) {

				if($arrayParametros['tipoCaixa'] === 'caixaAlta') {

					if(is_numeric(&$arrayParametros['posicaoCaractere'])) {

						$arrayParametros['auxPalavra']{$arrayParametros['posicaoCaractere']} =& strtoupper($arrayParametros['auxPalavra']{$arrayParametros['posicaoCaractere']});
					}

					elseif($arrayParametros['posicaoCaractere'] === NULL) {

						$arrayParametros['auxPalavra'][$arrayParametros['countPalavras']] =& strtoupper($arrayParametros['auxPalavra'][$arrayParametros['countPalavras']]);
					}
				}

				elseif($arrayParametros['tipoCaixa'] !== 'caixaBaixa') {

					$arrayParametros['auxPalavra'] =& $arrayParametros['palavra'][$arrayParametros['countPalavras']];
				}
			}

			else {

				$arrayParametros['auxPalavra'] =& $arrayParametros['palavra'][$arrayParametros['countPalavras']];
			}

			$arrayParametros['arrayConcatenacaoPalavras'][] = $arrayParametros['auxPalavra'];

			if($arrayParametros['countPalavras'] == ($arrayParametros['quantidadePalavras'] - 1)) {

				$concatenacaoPalavras =& self::adicionarSeparador(&$arrayParametros['arrayConcatenacaoPalavras'], &$arrayParametros['quantidadePalavras'], $arrayParametros['separador']);
				self::$_arrayNaoInflexionaveis = self::$_arrayPluralIrregular = self::$_arrayRegrasInflexao = $arrayParametros = NULL;

				return $concatenacaoPalavras;
			}
		}
	}
}
?>